﻿using System;
using System.Diagnostics;
using System.IO.Ports;
using System.Threading.Tasks;
using System.Timers;
using TruckScale.Helpers;
using static TruckScale.Helpers.LogHelper;

namespace TruckScale.ViewModels
{
  public partial class MainViewModel
  {
    private string _weighStr; //绑定界面属性：重量数字，数字改变时，延时稳定属性为false，延时稳定计时器重新开始计时
    public string WeighStr
    {
      get { return _weighStr; }
      set
      {
        if (_weighStr != value)
        {
          IsDelayStable = false;

          dsTimer?.Stop();
          dsTimer?.Start();

          _weighStr = value;

          if (Convert.ToDecimal(value) < Convert.ToDecimal(Global._weighConfig["MinWeight"]))
          {
            weighingStatus = WeighingStatus.Ready;
          }
          else //大于最小称重重量时，如果不是已完成，再修改为称重中，否则一直是已完成状态
          {
            if (weighingStatus != WeighingStatus.Completed)
            {
              weighingStatus = WeighingStatus.InProgress;
            }
          }

          CheckBtnEnable();
        }
      }
    }

    private bool _isDelayStable;
    public bool IsDelayStable
    {
      get => _isDelayStable;
      set
      {
        if (_isDelayStable != value)
        {
          _isDelayStable = value;
          CheckBtnEnable();
          if (value)
          {
            SetLog($"稳定重量:{WeighStr}", LogType.HardwareLogger);
          }
        }
      }
    } //绑定界面属性：延时稳定标记

    private bool _isSPConnected;
    public bool IsSPConnected
    {
      get => _isSPConnected; set
      {
        if (_isSPConnected != value)
        {
          _isSPConnected = value;
          CheckBtnEnable();
        }
      }
    } //绑定界面属性：称重串口通信连接标记    

    private SerialPort weighSP = new SerialPort(); //称重串口
    private bool weighSpClosing; //正在关闭称重串口的标识
    private bool weighSpListening; //称重串口正在接收数据的标识
    private byte[] weighSpBuf; //接收称重串口数据的buffer
    private Timer dsTimer;  //delaystableTimer 延时稳定计时器
    private Timer weighSpDetectTimer; //称重串口状态检测定时器

    private void InitWeighNumProps()
    {
      //weighSP = new SerialPort();

      //打开称重串口和设置协议，若切换串口，要先关闭之前的，再重新打开新的
      if (weighSP.IsOpen)
      {
        weighSpClosing = true;
        while (weighSpListening) ;
        weighSP.Close();
        SetLog("关闭称重串口:" + weighSP.PortName, LogType.HardwareLogger);
        weighSpClosing = false;
      }

      string[] spParam = Global._weighConfig["WeighSP"].Split(',');
      if (spParam.Length != 5) { SetLog("称重串口配置错误", LogType.HardwareLogger, LogLevel.Error); return; }
      weighSP.PortName = spParam[0];
      weighSP.BaudRate = Convert.ToInt32(spParam[1]);
      weighSP.Parity = (Parity)Enum.Parse(typeof(Parity), spParam[2]);
      weighSP.DataBits = Convert.ToInt32(spParam[3]);
      weighSP.StopBits = (StopBits)Convert.ToInt32(spParam[4]);
      weighSP.DtrEnable = true;
      weighSP.RtsEnable = true;
      weighSP.DataReceived += new SerialDataReceivedEventHandler(WeighSP_DataReceived);

      try
      {
        weighSP.Open();
        SetLog("打开称重串口:" + weighSP.PortName, LogType.HardwareLogger);
      }
      catch (Exception e)
      {
        SetLog("称重串口打开失败:" + e.Message, LogType.HardwareLogger);
      }

      //初始化延时稳定检测定时器资源
      if (dsTimer == null)
      {
        dsTimer = new Timer
        {
          Interval = Convert.ToDouble(Global._weighConfig["StableDelay"]) * 1000
        };
      }

      dsTimer.Elapsed += (s, args) =>
      {
        if (!string.IsNullOrEmpty(WeighStr))
        {
          IsDelayStable = true;
        }
      };

      //初始化串口通信检测定时器资源
      if (weighSpDetectTimer == null)
      {
        weighSpDetectTimer = new Timer
        {
          Interval = 2000
        };
      }

      weighSpDetectTimer.Elapsed += (s, args) =>
      {
        if (weighSpBuf == null)
        {
          IsSPConnected = false;
          WeighStr = null;
        }
      };
    }

    private void WeighSP_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
      if (weighSpClosing)
      {
        return;
      }

      try
      {
        weighSpListening = true;//设置标记，说明我已经开始处理数据。  

        //获取串口Hex数据，放到全局数组中
        SerialPort sp = (SerialPort)sender;
        if (sp.PortName.Equals(weighSP.PortName))
        {
          weighSpBuf = new byte[64];
          while (sp.BytesToRead < 12) ; //这个数字应该和协议位数相同，如果大于协议位数，数字显示会有延迟
          sp.Read(weighSpBuf, 0, 64);
          //int bytesToRead = sp.BytesToRead;
          //weighSpBuf = new byte[bytesToRead];
          //sp.Read(weighSpBuf, 0, weighSpBuf.Length);
          WeighStr = ProtocolParseHelper.ProtocolParse(weighSpBuf);
          
          weighSpBuf = null;
          weighSpDetectTimer?.Stop();
          weighSpDetectTimer?.Start();
          IsSPConnected = true;
        }
      }
      catch (Exception ex)
      {
        SetLog("称重串口通信异常:" + ex.Message, LogType.HardwareLogger, LogLevel.Error);
      }
      finally
      {
        weighSpListening = false;//我用完了，ui可以关闭串口了。
      }
    }
  }
}
